home *** CD-ROM | disk | FTP | other *** search
- /* Stuff generic to all Ethernet controllers
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include "global.h"
- #ifdef ETHER
- #include "mbuf.h"
- #include "iface.h"
- #include "arp.h"
- #include "enet.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: enet.c,v 1.11 1997/07/31 00:44:20 root Exp root $";
- #endif
-
- unsigned char Ether_bdcst[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- static struct mbuf *htonether(struct ether *ether,struct mbuf *data);
-
-
-
- /* Convert Ethernet header in host form to network mbuf */
- struct mbuf *
- htonether(
- struct ether *ether,
- struct mbuf *data
- ){
- char *cp;
- struct mbuf *bp;
-
- if(data == NULL || (bp = pushdown (data, ETHERLEN)) == NULLBUF)
- return NULLBUF;
-
- cp = (char *) bp->data;
-
- memcpy (cp, ether->dest, EADDR_LEN);
- cp += EADDR_LEN;
- memcpy (cp, ether->source, EADDR_LEN);
- cp += EADDR_LEN;
- (void) put16 ((unsigned char *) cp, (int16) ether->type);
-
- return bp;
- }
-
-
-
- /* Extract Ethernet header */
- int
- ntohether(
- struct ether *ether,
- struct mbuf **bpp
- ){
- (void) pullup (bpp, ether->dest, EADDR_LEN);
- (void) pullup (bpp, ether->source, EADDR_LEN);
- ether->type = pull16 (bpp);
- return ETHERLEN;
- }
-
-
-
- /* Format an Ethernet address into a printable ascii string */
- char *
- pether(
- char *out,
- char *addr
- ){
- sprintf(out,"%02x:%02x:%02x:%02x:%02x:%02x",
- uchar(addr[0]),uchar(addr[1]),
- uchar(addr[2]),uchar(addr[3]),
- uchar(addr[4]),uchar(addr[5]));
- return out;
- }
-
-
-
- /* Convert an Ethernet address from Hex/ASCII to binary */
- int
- gether(
- register char *outorig,
- register const char *cp
- ){
- register int i;
- unsigned char *out = (unsigned char *) outorig;
-
- for (i = 6; i != 0; i--) {
- *out++ = uchar(htoi (cp));
- if ((cp = strchr (cp, ':')) == NULL) /* Find delimiter */
- break;
- cp++; /* and skip over it */
- }
- return i;
- }
-
-
-
- /* Send an IP datagram on Ethernet */
- int
- enet_send(
- struct mbuf *bp, /* Buffer to send */
- struct iface *iface, /* Pointer to interface control block */
- uint32 gateway, /* IP address of next hop */
- int prec OPTIONAL,
- int del OPTIONAL,
- int tput OPTIONAL,
- int rel OPTIONAL
- ){
- char *egate;
-
- if (gateway == iface->broadcast) /* This is a broadcast IP datagram */
- return (*iface->output) (iface, (char *) Ether_bdcst, iface->hwaddr, IP_TYPE, bp);
-
- egate = res_arp (iface, ARP_ETHER, gateway, bp);
- if(egate != NULLCHAR)
- return (*iface->output) (iface, egate, iface->hwaddr, IP_TYPE, bp);
- return 0;
- }
-
-
-
- /* Send a packet with Ethernet header */
- int
- enet_output(
- struct iface *iface, /* Pointer to interface control block */
- const char *dest, /* Destination Ethernet address */
- char *source, /* Source Ethernet address */
- int16 type, /* Type field */
- struct mbuf *data /* Data field */
- ){
- struct ether ep;
- struct mbuf *bp;
-
- memcpy (ep.dest, dest, EADDR_LEN);
- memcpy (ep.source, source, EADDR_LEN);
- ep.type = type;
- if ((bp = htonether(&ep,data)) == NULLBUF) {
- free_p (data);
- return -1;
- }
- return (*iface->raw)(iface,bp);
- }
-
-
-
- /* Process incoming Ethernet packets. Shared by all ethernet drivers. */
- void
- eproc(
- struct iface *iface,
- struct mbuf *bp
- ){
- struct ether hdr;
-
- /* Remove Ethernet header and kick packet upstairs */
- (void) ntohether(&hdr,&bp);
-
- if(memcmp (hdr.dest, iface->hwaddr, EADDR_LEN) && memcmp (hdr.dest, Ether_bdcst, EADDR_LEN)) {
- free_p(bp);
- return;
- }
-
- switch(hdr.type) {
- case REVARP_TYPE:
- case ARP_TYPE:
- arp_input (iface, bp);
- break;
- case IP_TYPE:
- (void) ip_route (iface, bp, hdr.dest[0] & 1);
- break;
- default:
- free_p (bp);
- break;
- }
- }
-
- #endif /* ETHER */
-